#ifndef	LANGUAGE_SYMBOLS_H
#define	LANGUAGE_SYMBOLS_H

#include "StringTable.h"
#include <memory>
#include <iostream>
#include <vector>
#include <map>
using namespace std;
using namespace Wll;

//SymbolTypes类声明部分

//Symbols
class SymbolTypes
{
public:
    int type_code;
public:
    SymbolTypes(const char* type_name);
    SymbolTypes();

public:
    bool operator< (const SymbolTypes& that) const;
    bool operator== (const SymbolTypes& that) const;
    bool operator<= (const SymbolTypes& that) const
    {
        return (*this < that || *this == that);
    }
    bool operator!= (const SymbolTypes& that) const
    {
        return !(*this == that);
    }
    bool operator> (const SymbolTypes& that) const
    {
        return !(*this < that || *this == that);
    }
    bool operator>= (const SymbolTypes& that) const
    {
        return !(*this < that);
    }
    std::string ToString() const;

private:
    static StringTable type_table;
public:
    static void Load(istream& i);
    static void Save(ostream& o);

public:
    static const SymbolTypes ANY_TYPE;   //任意类型
    static const SymbolTypes VOID_TYPE;		//VOID类型，作为空类型
    static const SymbolTypes VARIABLE_TYPE;	//文法变量类型
    static const SymbolTypes REMARK_TYPE;		//文法标记类型
    static const SymbolTypes CONSTANT_TYPE;	//文法常量类型
//自動類型轉換的順序是由低向高
    static const SymbolTypes CHAR_TYPE;            //单个字符类型
    static const SymbolTypes INTEGER_TYPE;		//整数类型
    static const SymbolTypes LONG_TYPE;		//长整数类型
    static const SymbolTypes FLOAT_TYPE;		//浮点数类型
    static const SymbolTypes DOUBLE_TYPE;		//双精度浮点数类型
    static const SymbolTypes STRING_TYPE;		//字符串类型
    static const SymbolTypes REFERENCE_TYPE;    //引用类型

    static const SymbolTypes COMPACT_TYPE;      //组合类型
    static const SymbolTypes S_EXP_TYPE;		//S表达式类型
    static const SymbolTypes LIST_TYPE;		//数组类型
    static const SymbolTypes MAP_TYPE;		//字典类型

    static const SymbolTypes USER_DEFINE_TYPE;    //用户自定义类型
};

//Symbols类声明部分

//when type =
//	VARIABLE_SYMBOL: value = index of variable in names table
//	CONSTANT_SYMBOL: value = code of character
//	REMARK_SYMBOL: 	 value = remark define value 
class Symbols
{
public:
    SymbolTypes type;
	union {
		int value;
		char c;
		int i;
		long l;
		float f;
		double d;
		shared_ptr<string>* s;
		shared_ptr< vector<Symbols> >* list;
		shared_ptr< map<string, Symbols> >* m;
		Symbols* reference;		
	};
private:
	void Init();
	void Destroy();
	void Copy(const Symbols& that);
public:
	Symbols();
	Symbols(const Symbols& that);
	Symbols& operator= (const Symbols& that);
	~Symbols();
	Symbols(const char* variable);
	Symbols(char constant);
	Symbols(SymbolTypes type, const char* remark);
    Symbols(const char* type_name, const char* value);
	Symbols(SymbolTypes symbol_type, char c);
	Symbols(int i);
	Symbols(long l);
	Symbols(float f);
	Symbols(double d);
	Symbols(Symbols* reference);
	Symbols(SymbolTypes type , vector<Symbols> symbols);
	Symbols(SymbolTypes type);
    Symbols(SymbolTypes type, SymbolTypes value);
	bool operator== (const Symbols& that) const;
	bool operator< (const Symbols& that) const;
    bool match(const Symbols& that) const;
public:
	vector<Symbols>& GetList();
	const vector<Symbols>& GetList() const;
	map<string, Symbols>& GetMap();
	const map<string, Symbols>& GetMap() const;
public:
	bool IsVariable()const;
	bool IsConstant()const;
	bool IsRemark()const;
	string ToString()const;
	void Display(ostream& o) const;
	void Dump(ostream& o) const;
    void Save(ostream& o) const;
    void Load(istream& i);
    static void Save();
    static void Load();
public:
	static StringTable variable_table;
	static StringTable remark_table;
    static StringTable value_table;

public:
    static const Symbols VOID;
//支持文法解析
    static const Symbols NULL_SYMBOL;	//在文法表示中用空expression表示
    static const Symbols END_SYMBOL;

    static const Symbols ANY_SYMBOL;
    static const Symbols ANY_VARIABLE;
    static const Symbols ANY_REMARK;
    static const Symbols ANY_CONSTANT;
    static const Symbols ANY_CHAR;
    static const Symbols ANY_INTEGER;
    static const Symbols ANY_LONG;
    static const Symbols ANY_FLOAT;
    static const Symbols ANY_DOUBLE;
    static const Symbols ANY_STRING;		//字符串类型
    static const Symbols ANY_REFERENCE;    //引用类型

    static const Symbols ANY_COMPACT;      //组合类型
    static const Symbols ANY_S_EXP;		//S表达式类型
    static const Symbols ANY_LIST;		//数组类型
    static const Symbols ANY_MAP;		//字典类型
//支持WLL0文法自解释
    //标志解释文法版本号
    static const Symbols WLL0;
    static const Symbols WLL1;
    static const Symbols WLL2;
    static const Symbols WLL3;

    static const Symbols REMARK_TRANSLATION;
    static const Symbols REMARK_SOURCE_RULE;
    static const Symbols REMARK_DESTINATION_RULE;
    static const Symbols REMARK_RULE;
    static const Symbols REMARK_ROOT_SYMBOL;
    static const Symbols REMARK_EXPRESSION;
    static const Symbols REMARK_SUB_SYMBOL;
    static const Symbols REMARK_VARIABLE;
    static const Symbols REMARK_CONSTANT;
    static const Symbols REMARK_REMARK;

//支持S表达式求解(WLL1文法自解释)
    static const Symbols EVAL;				//执行求值动作,受外部$IGNORE制约
    static const Symbols EXEC;				//执行求值动作,不受外部$IGNORE制约
    static const Symbols REMARK_IGNORE;		//忽略$IGNORE$LEFT_QUOTE...$RIGHT_QUOTE括号内的符号的求值
    static const Symbols IGNORE_BEGIN;		//范围操作符号,忽略$IGNORE_BEGIN...$IGNORE_END括号内的符号求值，并把它们Compact as a COMPACT_SYMBOL压栈
    static const Symbols IGNORE_END;		//范围操作符号
    static const Symbols COMPACT;			//COMPACT操作，把SYMBOL,...,SYMBOL=>COMPACT_SYMBOL
    static const Symbols COMPACT_BEGIN;		//范围操作符号，把COMPACT_BEGIN...COMPACT_END范围内的运算结果COMPACT AS A COMPACT_SYMBOL压栈
    static const Symbols COMPACT_END;		//范围操作符号
    static const Symbols LEFT_QUOTE;		//S表达式的左括号,用来界定前缀表达式
    static const Symbols RIGHT_QUOTE;		//S表达式的右括号,用来界定前缀表达式
    static const Symbols SEPERATOR;			//S表达式的参数分隔符号,用来分隔前缀表达式参数
    static const Symbols LOAD_TRANSLATIONS;	//调用Wll0Loader加载文法规则
    static const Symbols CLEAR_TRANSLATIONS;//清空Interpret context中的language_grammar
    static const Symbols ADD_TRANSLATIONS;	//调用Wll0Loader加载文法规则,和LOAD_TRANSLATIONS的区别是ADD_TRANSLATIONS不会清空之前的文法规则
    static const Symbols CREATE_COMPILER;   //从Interpret context中的language_grammar创建Compiler
//支持Ｓ表达式求值
    static const Symbols LIST;
    static const Symbols APPEND;
    static const Symbols CAR;
    static const Symbols CDR;
//控制結構
    static const Symbols COND;				//条件控制
    static const Symbols LOOP;				//循环控制
    static const Symbols CALL;			//执行call命令
    static const Symbols FCALL;				//從文件加載文法進行調用
//支持变量存储
    static const Symbols LREF;				//左值引用(write)
    static const Symbols RREF;				//右值引用(read)
    static const Symbols DEF;				//变量定义
    static const Symbols SET;				//变量赋值,如果变量之前没有定义则自动定义
    static const Symbols GET;				//变量引用,如果变量没有定义,返回空值
    static const Symbols PUSH_DATA;			//初始化变量空间并压栈
    static const Symbols POP_DATA;			//销毁本层变量空间并出栈
    static const Symbols PUSH;				//表达式值压入参数栈顶
    static const Symbols POP;				//参数栈顶值出栈到变量
//支持数据结构
    static const Symbols ARRAY;				//创建Symbols(LIST_SYMBOL)数值变量
    static const Symbols MAP;				//创建Symbols(MAP_SYMBOL)字典变量

//類型常量
    static const Symbols CHAR;
    static const Symbols INTEGER;
    static const Symbols LONG;
    static const Symbols FLOAT;
    static const Symbols DOUBLE;
    static const Symbols STRING;

    static const Symbols SYMBOL;
    static const Symbols CAST;			//類型轉換
//支持运算控制
    static const Symbols ADD;				//整数加,1..n个参数
    static const Symbols SUB;				//整数减,1..n个参数
    static const Symbols MUL;				//整数乘,1..n个参数
    static const Symbols DIV;				//整数除,1..n个参数
    static const Symbols TRUE;				//逻辑真
    static const Symbols FALSE;				//逻辑假
    static const Symbols EQ;				//等于
    static const Symbols SAME;				//字符比較
    static const Symbols LT;				//小于(字典序)
    static const Symbols AND;				//与
    static const Symbols OR;				//或
    static const Symbols NOT;				//非

    static const Symbols SUB_STR;		//取子串,from,size,1或2個參數
    static const Symbols SHELL;				//执行shell命令
    static const Symbols CAT;				//从文件中加载符号,支持INCLUDE特性

    static const Symbols IDLE;			//不做任何操作,简单忽略
};


bool operator== (const vector<Symbols>& a, const vector<Symbols>& b);
bool operator< (const vector<Symbols>& a, const vector<Symbols>& b);
bool operator== (const map<string,Symbols>& a, const map<string,Symbols>& b);
bool operator< (const map<string,Symbols>& a, const map<string,Symbols>& b);

istream& operator>> (istream& i,  vector<Symbols>& symbols);
ostream& operator<< (ostream& o, const Symbols& symbol);
ostream& operator<< (ostream& o, const vector<Symbols>& symbols);
int Split(const vector<Symbols>&symbols, Symbols seperator, vector< vector<Symbols> >& fields);
int SplitParameters(const vector<Symbols>&symbols, vector< vector<Symbols> >& fields);
int SplitParameters(vector<Symbols>::const_iterator begin, vector<Symbols>::const_iterator end, vector< vector<Symbols> >& fields);
//分解S表达式为符号表
//<expression>--><symbol>;
//<expression>--><symbol><expression>;
//<symbol>--><variable>;
//<symbol>--><constant>;
//<symbol>--><remark>;
//<symbol>--><s_expression>;
//<s_expression>-->$LEFT_QUOTE<expression_list>$RIGHT_QUOTE;
//<expression_list>--><expression>;
//<expression_list>--><expression>$SEPERATOR<expression_list>;
int SplitSList(const vector<Symbols>&symbols, vector< vector<Symbols> >& fields);
//分解表达式为符号列表
int SplitExpression(const vector<Symbols>&symbols, vector< vector<Symbols> >& fields);

void ComposeSList(vector<vector<Symbols> >::const_iterator begin, vector<vector<Symbols> >::const_iterator end, vector<Symbols>& slist);
std::vector<Symbols>& operator+= (std::vector<Symbols>& a, const std::vector<Symbols>& b);
std::vector<Symbols>& operator+= (std::vector<Symbols>& a, const std::string& b);
const std::string& ToString (std::string& str, const std::vector<Symbols>& symbols);

void AssertSymbolsType(vector<Symbols> symbols, SymbolTypes symbol_type);
//把輸入input_symbols轉換爲內部緊湊表示形式(EXPRESSION => COMPACT_SYMBOL, s表達式(A,B,C) => S_EXP_SYMBOL)
bool CompactSExpression(const std::vector<Symbols>& input_symbols, Symbols& compacted_input_symbols);
#endif	//LANGUAGE_SYMBOLS_H

